package com.sg.service.biz.component.nb;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.sg.common.util.CommonFunctionHelper;
import com.sg.dto.biz.component.req.*;
import com.sg.dto.biz.component.res.*;
import com.wicket.okrcomponent.common.exception.BizException;
import okhttp3.*;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ： 手工接入方法
 * @version 1.0
 * @since 2022/5/28 15:32
 */
@Service
public class NbResourceFile {

    @Trace(operationName = "M2执行三方文件上传接口（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public String uploadFileToOpenAI(ImplementResourceFileToThirdPartyReqDto reqDto) throws Exception {
        OkHttpClient client = new OkHttpClient();
        File file = CommonFunctionHelper.getBaseInfoFromLocal().getLocalFile().get(reqDto.getResourceFileRelaPath());
        // 创建请求体，包含文件和表单字段
        MultipartBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(),
                        RequestBody.create(MediaType.parse("application/octet-stream"), file))
                .addFormDataPart("purpose", "file-extract")
                .build();

        // 构建请求
        Request request = new Request.Builder()
                .url(reqDto.getIntelliQaAddress() + "/files")
                .post(requestBody)
                .addHeader("Authorization", "Bearer " + reqDto.getKey())
                .build();

        // 发送请求并获取响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new Exception("Unexpected code " + response);

            // 解析响应JSON以获取文件ID
            String responseString = response.body().string();
            JSONObject jsonResponse = JSONObject.parseObject(responseString);
            return jsonResponse.getString("id");
        }

    }

    /**
     * code:thirtPartFileUpload
     * name:M2执行三方文件上传接口（特殊方法）
     * desc:undefined
     * gen by moon at 12/6/2024, 10:03:37 PM
     **/
    @Trace(operationName = "M2执行三方文件上传接口（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementResourceFileToThirdPartyRespDto implementResourceFileToThirdParty(ImplementResourceFileToThirdPartyReqDto reqDto) {
        ImplementResourceFileToThirdPartyRespDto retData = new ImplementResourceFileToThirdPartyRespDto();
        try {
            String fileId = uploadFileToOpenAI(reqDto);
            retData.setThirtPartFileId(fileId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retData;
    }

    @Trace(operationName = "打印南艺区块链返回信息")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public Response print(Response reqDto) {
        return reqDto;
    }

    /**
     * code:resourceFileChain
     * name:M2执行资源文件上链（特殊方法)
     * desc:undefined
     * gen by moon at 12/8/2024, 3:21:57 AM
     **/
    @Trace(operationName = "M2执行资源文件上链（特殊方法)")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementEviFileChainRespDto implementEviFileChain(ImplementEviFileChainReqDto reqDto) {
        ImplementEviFileChainRespDto retData = new ImplementEviFileChainRespDto();
        // 你的appKey和生成signature的逻辑
        String appKey = reqDto.getAppKey();
        long timestamp = reqDto.getChainTimeMap(); // 使用当前时间戳
        String signature = reqDto.getChainSignature(); // 假设你有一个方法来生成signature

        // 创建一个OkHttpClient实例
        OkHttpClient client = new OkHttpClient();

        // 创建一个RequestBody，这里假设你的请求体是JSON格式的
        // 你需要根据实际情况来构造RequestBody


        JSONObject jsonBody = new JSONObject();
        jsonBody.put("userName", reqDto.getUserName());
        jsonBody.put("identType", reqDto.getIdentType());
        jsonBody.put("identNo", reqDto.getIdentNo());
        jsonBody.put("productId", reqDto.getProductId());
        jsonBody.put("workId", reqDto.getWorkId());
        jsonBody.put("stepId", reqDto.getStepId());
        jsonBody.put("itemList", reqDto.getItemList());

        RequestBody body = RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"),
                jsonBody.toJSONString() // 这里写你的请求体内容
        );

        // 创建一个Request对象
        Request request = new Request.Builder()
                .url(reqDto.getValidChainCreate()) // 替换成你的API端点
                .post(body)
                .addHeader("timestamp", String.valueOf(timestamp))
                .addHeader("appKey", appKey)
                .addHeader("signature", signature)
                .build();

        // 发送请求并获取响应
        try {
            Response response = client.newCall(request).execute();
            print(response);
            // 打印响应内容
            String responseBody = response.body().string();
            JSONObject responseData = JSON.parseObject(responseBody);
            if (responseData != null && responseData.getString("msg").equals("success")) {
                String data = responseData.getString("data");
                JSONObject dataJson = JSONObject.parseObject(data);
                retData.setChainAddress(dataJson.getString("chainAddress"));
                retData.setHashCal(dataJson.getString("hashCal"));
                retData.setDataId(dataJson.getLong("dataId"));
                retData.setDataHash(dataJson.getString("dataHash"));
            } else {

            }
        } catch (Exception e) {
            throw new BizException("-1", "M2执行资源文件上链异常:" + e.getMessage(), false);
        }
        return retData;
    }

    /**
     * code:obtainChainToken
     * name:M2生成上链签名（特殊方法)
     * desc:undefined
     * gen by moon at 12/8/2024, 3:22:29 AM
     **/
    @Trace(operationName = "M2生成上链签名（特殊方法)")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ObtainChainTokenRespDto obtainChainToken(ObtainChainTokenReqDto reqDto) {
        ObtainChainTokenRespDto retData = new ObtainChainTokenRespDto();
        Long time = reqDto.getChainCreateTime().getTime();
        String dataStr = time + reqDto.getAppKey() + reqDto.getAppSecret();
        String signature = md5Encrypt(dataStr);
        retData.setChainSignature(signature);
        retData.setChainTimeMap(time);
        return retData;
    }

    public static void main(String[] args) {
        NbInterfaceMode mo = new NbInterfaceMode();

        ImplementMutFeldToJsonStringReqDto mutiFieldToJsonStringReq = new ImplementMutFeldToJsonStringReqDto();
        mutiFieldToJsonStringReq.setCustomField1("hashCode");//SimpleFieldAssign//sourceId:2034676_1
        mutiFieldToJsonStringReq.setCustomFieldValue1("erewerjdsfjewrjejf");//SimpleFieldAssign//sourceId:2034681_1
        mutiFieldToJsonStringReq.setCustomField2("resourceFileName");//SimpleFieldAssign//sourceId:2034677_1
        mutiFieldToJsonStringReq.setCustomFieldValue2("my.doc");//SimpleFieldAssign//sourceId:2034679_1
        ImplementMutFeldToJsonStringRespDto ret = mo.implementMutFeldToJsonString(mutiFieldToJsonStringReq);

        NbResourceFile o = new NbResourceFile();
        ObtainChainTokenReqDto getToken = new ObtainChainTokenReqDto();
        getToken.setAppKey("UDSN5Yvg");
        getToken.setAppSecret("8igqRUFkC3JnEp7DAc60rT94NyIvWduP");
        getToken.setChainCreateTime(CommonFunctionHelper.getCurrentTime());
        ObtainChainTokenRespDto tokenInfo = o.obtainChainToken(getToken);

        ImplementEviFileChainReqDto impInfo = new ImplementEviFileChainReqDto();
        impInfo.setAppKey("UDSN5Yvg");
        impInfo.setChainSignature(tokenInfo.getChainSignature());
        impInfo.setChainTimeMap(tokenInfo.getChainTimeMap());


        impInfo.setUserName("胡睿哲");
        impInfo.setIdentType("组织");
        impInfo.setIdentNo("111");
        impInfo.setProductId(19l);
        impInfo.setWorkId(10l);
        impInfo.setStepId(31l);

        List<ItemDto> itemList = new ArrayList<>();
        ItemDto one = new ItemDto();
        one.setChName("");
        one.setEnName("");
        one.setEnValue(ret.getCustomText());
        itemList.add(one);
        impInfo.setItemList(itemList);

        ImplementEviFileChainRespDto impRet = o.implementEviFileChain(impInfo);
        System.out.println(impRet);
    }

    private String md5Encrypt(String dataStr) {
        try {
            MessageDigest m = MessageDigest.getInstance("MD5");
            m.update(dataStr.getBytes("UTF8"));
            byte s[] = m.digest();
            String result = "";
            for (int i = 0; i < s.length; i++) {
                result += Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6);
            }
            return result.toUpperCase();
        } catch (Exception e) {
            throw new BizException("-1", "", false);
        }
    }

    /**
     * code:receptionService
     * name:接收问答命令出参
     * desc:undefined
     * gen by moon at 12/10/2024, 12:00:16 AM
     **/
    @Trace(operationName = "接收问答命令出参")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public AddObjectStorageConfigRespDto addObjectStorageConfig(AddObjectStorageConfigReqDto reqDto) {
        return BeanUtil.toBean(reqDto, AddObjectStorageConfigRespDto.class);
    }

    /**
     * code:receptionService
     * name:M2执行智能沟通接收入参
     * desc:undefined
     * gen by moon at 12/10/2024, 12:00:48 AM
     **/
    @Trace(operationName = "M2执行智能沟通接收入参")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public ImplementSmartSessionReceiveFieldInputRespDto implementSmartSessionReceiveFieldInput(ImplementSmartSessionReceiveFieldInputReqDto reqDto) {
        return BeanUtil.toBean(reqDto, ImplementSmartSessionReceiveFieldInputRespDto.class);
    }

    /**
     * code:loadFileToMemory
     * name:M2从阿里云加载文件到内存（特殊方法）
     * desc:undefined
     * gen by moon at 12/10/2024, 12:01:06 AM
     **/
    @Trace(operationName = "M2从阿里云加载文件到内存（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public LoadFileFromAliYunRespDto loadFileFromAliYun(LoadFileFromAliYunReqDto reqDto) {
        // 创建阿里云OSS客户端
        OSS ossClient = new OSSClientBuilder().build(reqDto.getAliyunOssServiceAddress(), reqDto.getAliyunOssKey(), reqDto.getAliyunOssSecretKey());

        // 指定要下载的文件路径
        File file = null;
        try {
            file = File.createTempFile("oss-", ".tmp");
            file.deleteOnExit(); // 确保JVM退出时删除临时文件
            // 从OSS下载文件到本地
            String bucketName = reqDto.getAliyunOssBucketName();
            String objectName = reqDto.getFile();
            InputStream stream = ossClient.getObject(new com.aliyun.oss.model.GetObjectRequest(bucketName, objectName)).getObjectContent();
            Files.copy(stream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
        CommonFunctionHelper.getBaseInfoFromLocal().getLocalFile().put(reqDto.getFile(), file);


        return new LoadFileFromAliYunRespDto();
    }

    /**
     * code:loadFileToMemory
     * name:M2从minio加载文件到内存（特殊方法）
     * desc:undefined
     * gen by moon at 12/10/2024, 12:01:23 AM
     **/
    @Trace(operationName = "M2从minio加载文件到内存（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public LoadFileFromMinioRespDto loadFileFromMinio(LoadFileFromMinioReqDto reqDto) {
        // TODO ruizhe skai dong ; 12/10/2024, 12:01:23 AM
        return new LoadFileFromMinioRespDto();
    }

    /**
     * code:loadFileToMemory
     * name:M2从本地加载文件到内存（特殊方法）
     * desc:undefined
     * gen by moon at 12/10/2024, 12:01:40 AM
     **/
    @Trace(operationName = "M2从本地加载文件到内存（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public LoadFileFromLocalRespDto loadFileFromLocal(LoadFileFromLocalReqDto reqDto) {
        File file = new File(reqDto.getLocalStorageRootPath() + "/" + reqDto.getFile());
        CommonFunctionHelper.getBaseInfoFromLocal().getLocalFile().put(reqDto.getFile(), file);
        return new LoadFileFromLocalRespDto();
    }
    //手工接入方法
}
